#ifndef __M_ROUTE_H__
#define __M_ROUTE_H__
/**
 * @file route.hpp
 * @brief 路由管理模块
 * 
 * 提供路由键验证和消息路由匹配的核心功能
 * 包含三个静态方法：
 * 1. 验证路由键合法性
 * 2. 验证绑定键合法性
 * 3. 根据交换器类型执行路由匹配
 */
#include <iostream>
#include "../common/logger.hpp"
#include "../common/helper.hpp"
#include "../common/msg.pb.h"

namespace bitmq
{
    /**
     * @class Router
     * @brief 提供路由键验证和消息路由匹配的核心功能
     * 
     * 包含三个静态方法：
     * 1. 验证路由键合法性
     * 2. 验证绑定键合法性
     * 3. 根据交换器类型执行路由匹配
     */
    class Router 
    {
    public:
        /**
         * @brief 验证路由键的合法性
         * @param routing_key 待验证的路由键字符串
         * @return bool 验证结果（true=合法，false=非法）
         * 
         * 合法字符规则：
         * - 小写字母 (a-z)
         * - 大写字母 (A-Z)
         * - 数字 (0-9)
         * - 下划线 (_) 和点号 (.)
         */
        static bool isLegalRoutingKey(const std::string &routing_key) 
        {
            // 遍历检查每个字符是否符合合法字符集
            for (auto &ch : routing_key) 
            {
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    (ch == '_' || ch == '.')) {
                    continue;
                }
                return false;
            }
            return true;
        }

        /**
         * @brief 验证绑定键的合法性
         * @param binding_key 待验证的绑定键字符串
         * @return bool 验证结果（true=合法，false=非法）
         * 
         * 验证规则：
         * 1. 字符合法性：允许 a-z, A-Z, 0-9, ., _, *, #
         * 2. 通配符独立规则：* 和 # 必须作为独立单词存在
         * 3. 通配符连续规则：禁止 * 和 # 连续出现（包括交叉连续）
         */
        static bool isLegalBindingKey(const std::string &binding_key) 
        {
            // 规则1：检查非法字符
            for (auto &ch : binding_key) {
                if ((ch >= 'a' && ch <= 'z') ||
                    (ch >= 'A' && ch <= 'Z') ||
                    (ch >= '0' && ch <= '9') ||
                    (ch == '_' || ch == '.') ||
                    (ch == '*' || ch == '#')) {
                    continue;
                }
                return false;
            }
            
            // 规则2：分割后检查通配符独立性
            std::vector<std::string> sub_words;
            StrHelper::split(binding_key, ".", sub_words);
            for (std::string &word : sub_words) 
            {
                // 通配符必须独立存在（单词长度>1且包含通配符即为非法）
                if (word.size() > 1 && 
                    (word.find("*") != std::string::npos ||
                     word.find("#") != std::string::npos)) {
                    return false;
                }
            }
            
            // 规则3：检查通配符连续情况
            for (int i = 1; i < sub_words.size(); i++) 
            {
                // 禁止的连续组合: [#,*] -> [#] 或 [*] -> [#] 或 [#] -> [*]
                if ((sub_words[i] == "#" && sub_words[i - 1] == "*") ||
                    (sub_words[i] == "#" && sub_words[i - 1] == "#") ||
                    (sub_words[i] == "*" && sub_words[i - 1] == "#")) 
                {
                    return false;
                }
            }
            return true;
        }

        /**
         * @brief 执行消息路由匹配
         * @param type 交换器类型（DIRECT/FANOUT/TOPIC）
         * @param routing_key 消息的路由键
         * @param binding_key 队列的绑定键
         * @return bool 匹配结果（true=匹配成功，false=匹配失败）
         * 
         * 匹配逻辑：
         * - DIRECT类型：需完全相等
         * - FANOUT类型：始终匹配
         * - TOPIC类型：使用动态规划进行通配符模式匹配
         */
        static bool route(ExchangeType type, const std::string &routing_key, const std::string &binding_key) {
            // 直连交换器：精确匹配
            if (type == ExchangeType::DIRECT) 
            {
                return (routing_key == binding_key);
            }
            // 广播交换器：无条件匹配
            else if (type == ExchangeType::FANOUT) 
            {
                return true;
            }
            
            // 主题交换器：使用动态规划进行通配符匹配
            // 步骤1：分割绑定键和路由键
            std::vector<std::string> bkeys, rkeys;
            int n_bkey = StrHelper::split(binding_key, ".", bkeys);
            int n_rkey = StrHelper::split(routing_key, ".", rkeys);
            
            // 步骤2：初始化动态规划表 (n_bkey+1 x n_rkey+1)
            std::vector<std::vector<bool>> dp(n_bkey + 1, std::vector<bool>(n_rkey + 1, false));
            dp[0][0] = true;  // 空键匹配空键
            
            // 步骤3：处理绑定键起始的#通配符（多级通配）
            for(int i = 1; i <= bkeys.size(); i++) 
            {
                if (bkeys[i - 1] == "#") 
                {
                    dp[i][0] = true;
                    continue;
                }
                break;  // 遇到非#通配符立即停止
            }
            
            // 步骤4：动态规划填表
            for (int i = 1; i <= n_bkey; i++) 
            {
                for (int j = 1; j <= n_rkey; j++) 
                {
                    // 情况1：精确匹配或*单级通配
                    if (bkeys[i - 1] == rkeys[j - 1] || bkeys[i - 1] == "*") 
                    {
                        dp[i][j] = dp[i - 1][j - 1];  // 继承左上角状态
                    }
                    // 情况2：#多级通配
                    else if (bkeys[i - 1] == "#") 
                    {
                        // 状态转移：继承上方/左方/左上方任意真值
                        dp[i][j] = dp[i - 1][j - 1] | dp[i][j - 1] | dp[i - 1][j];
                    }
                }
            }
            
            // 步骤5：返回最终匹配结果
            return dp[n_bkey][n_rkey];
        }
    };
}

#endif